#include "ULMNN_Manager.h"
#include"UserManager.h"
#include "ChattingRoom.h"
extern ChattingRoomManager chat_room_manager;
extern UserManager user_manager;

ULMNN_Manager* ULMNN_Manager::instance=nullptr;

ULMNN_Manager::ULMNN_Manager() {
    if(!fs::exists(ULMNN_DIR))fs::create_directories(ULMNN_DIR);
}

void ULMNN_Manager::create_new_file(string file_path, int user_id) {
    try{
    ofstream ofs;
    ofs.open(file_path, ios::out);
    UserLatestMsgNumNotify user_latest_msg_num_notify(user_id);
    ofs << user_latest_msg_num_notify.serialize().dump(4) << endl;
    ofs.close();
    }
    catch(exception&e){
        throw e;
    }
}

void ULMNN_Manager::save_to_file(int user_id, const UserLatestMsgNumNotify& user_latest_msg_num_notify) {
    string file_path = get_user_latest_msg_num_notify_file_path(user_id);
    try{
        string temp_file_path = file_path + ".tmp"; // 创建临时文件路径
        ofstream ofs;

        ofs.open(temp_file_path, ios::out);
        ofs << user_latest_msg_num_notify.serialize().dump(4) << endl; // 写入数据到临时文件
        ofs.close(); // 关闭临时文件
        fs::rename(temp_file_path, file_path); // 替换原文件
    }
    catch(exception&e){
        throw e;
    }
}

void ULMNN_Manager::load_from_file(int user_id, UserLatestMsgNumNotify& user_latest_msg_num_notify){
    try{
        string file_path = get_user_latest_msg_num_notify_file_path(user_id);
        if(!fs::exists(file_path)){
            create_new_file(file_path,user_id); 
            user_latest_msg_num_notify = UserLatestMsgNumNotify(user_id);
            return ;
        }

        ifstream ifs;
        ifs.open(file_path, ios::in);
        json j;
        ifs >> j;
        user_latest_msg_num_notify.unserialize(j);
        ifs.close();
    }
    catch(exception&e){
        throw e;
    }
}

void ULMNN_Manager::save_all_user_latest_msg_num_notify(){
    try{
    for(auto& x:user_latest_msg_num_notify_map){
        save_to_file(x.first, x.second);
    }
}
    catch(exception&e){
        throw e;
    }
}

ULMNN& ULMNN_Manager::QuickLoadUserLatestMsgNumNotify(int user_id){
    if(user_latest_msg_num_notify_map.find(user_id)==user_latest_msg_num_notify_map.end()){
        try{
            string file_path = get_user_latest_msg_num_notify_file_path(user_id);
            load_from_file(user_id, user_latest_msg_num_notify_map[user_id]);
        }
        catch(exception&e){
            throw e;
        }
    }
    return user_latest_msg_num_notify_map[user_id];
}

void ULMNN_Manager::add_one_num(int user_id, string chat_room_id, string time){
    try{
        auto& user_latest_msg_num_notify = QuickLoadUserLatestMsgNumNotify(user_id);
        user_latest_msg_num_notify.add_one_num(chat_room_id, time);
    }catch(exception&e){
        throw e;
    }
}

void ULMNN_Manager::send_latest_msg_num(int user_id, int socket_fd){
    try{
        auto& user_latest_msg_num_notify = QuickLoadUserLatestMsgNumNotify(user_id);
        user_latest_msg_num_notify.send_latest_msg_num(socket_fd);
    }catch(exception&e){
        throw e;
    }
}

void ULMNN_Manager::SendOrSaveUserLatestMsgNumNotify_regularly(int clear_frequency){
    while (true){
        try{
            this_thread::sleep_for(chrono::seconds(clear_frequency));
            lock_guard<mutex> lock(user_latest_msg_num_notify_map_mutex);
            for(auto it = user_latest_msg_num_notify_map.begin(); it != user_latest_msg_num_notify_map.end();){
                if(user_manager.is_online(it->first)){
                    send_latest_msg_num(it->first, user_manager.get_sockfd(it->first));
                    it = user_latest_msg_num_notify_map.erase(it); // 更新迭代器到下一个有效位置
                } else {
                    ++it; 
                }
            }
            save_all_user_latest_msg_num_notify();
        }catch(exception&e){
            throw e;
        }
    }
}

ULMNN_Manager* ULMNN_Manager::get_instance(){
    if(instance==nullptr){
        instance=new ULMNN_Manager();
    }
    return instance;
}

string ULMNN_Manager::get_user_latest_msg_num_notify_file_path(int user_id){
    return ULMNN_DIR + to_string(user_id) + ".json";
}

void ULMNN_Manager::add_num_for_user_in_chat_room(int sender_id, string chat_room_id, string time) {
    shared_ptr<ChatRoom> chat_room;
    chat_room_manager.QuickLoadChatContent(chat_room_id, chat_room);
    if(chat_room==nullptr){
        throw runtime_error("chat room not exist");
    }

    auto user_list=chat_room->get_user_list();
    for(auto& x:user_list){
        if(x.first!=sender_id){
            add_one_num(x.first, chat_room_id, time);
        }
    }
    #ifdef DEBUG
    save_all_user_latest_msg_num_notify();
    #endif
}
